<?php

/**
 * EasyShipApi
 * PHP version 8.3.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */

/**
 * Selling Partner API for Easy Ship.
 *
 * Use the Selling Partner API for Easy Ship to build applications for sellers to manage and ship Amazon Easy Ship orders. With this API, you can get available time slots, schedule and reschedule Easy Ship orders, and print shipping labels, invoices, and warranties. To review the differences in Easy Ship operations by marketplace, refer to [Marketplace support](https://developer-docs.amazon.com/sp-api/docs/easyship-api-v2022-03-23-use-case-guide#marketplace-support).
 *
 * The version of the OpenAPI document: 2022-03-23
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.9.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace SpApi\Api\easyship\v2022_03_23;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use SpApi\ApiException;
use SpApi\AuthAndAuth\RestrictedDataTokenSigner;
use SpApi\Configuration;
use SpApi\HeaderSelector;
use SpApi\Model\easyship\v2022_03_23\CreateScheduledPackageRequest;
use SpApi\Model\easyship\v2022_03_23\CreateScheduledPackagesRequest;
use SpApi\Model\easyship\v2022_03_23\CreateScheduledPackagesResponse;
use SpApi\Model\easyship\v2022_03_23\ListHandoverSlotsRequest;
use SpApi\Model\easyship\v2022_03_23\ListHandoverSlotsResponse;
use SpApi\Model\easyship\v2022_03_23\Package;
use SpApi\Model\easyship\v2022_03_23\Packages;
use SpApi\Model\easyship\v2022_03_23\UpdateScheduledPackagesRequest;
use SpApi\ObjectSerializer;
use Symfony\Component\RateLimiter\LimiterInterface;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;

/**
 * EasyShipApi Class Doc Comment.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */
class EasyShipApi
{
    public ?LimiterInterface $createScheduledPackageRateLimiter;
    public ?LimiterInterface $createScheduledPackageBulkRateLimiter;
    public ?LimiterInterface $getScheduledPackageRateLimiter;
    public ?LimiterInterface $listHandoverSlotsRateLimiter;
    public ?LimiterInterface $updateScheduledPackagesRateLimiter;
    protected ClientInterface $client;

    protected Configuration $config;

    protected HeaderSelector $headerSelector;

    /**
     * @var int Host index
     */
    protected int $hostIndex;

    private bool $rateLimiterEnabled;
    private InMemoryStorage $rateLimitStorage;

    /**
     * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        Configuration $config,
        ?ClientInterface $client = null,
        ?bool $rateLimiterEnabled = true,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->config = $config;
        $this->rateLimiterEnabled = $rateLimiterEnabled;

        if ($rateLimiterEnabled) {
            $this->rateLimitStorage = new InMemoryStorage();

            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('EasyShipApi-createScheduledPackage'), $this->rateLimitStorage);
            $this->createScheduledPackageRateLimiter = $factory->create('EasyShipApi-createScheduledPackage');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('EasyShipApi-createScheduledPackageBulk'), $this->rateLimitStorage);
            $this->createScheduledPackageBulkRateLimiter = $factory->create('EasyShipApi-createScheduledPackageBulk');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('EasyShipApi-getScheduledPackage'), $this->rateLimitStorage);
            $this->getScheduledPackageRateLimiter = $factory->create('EasyShipApi-getScheduledPackage');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('EasyShipApi-listHandoverSlots'), $this->rateLimitStorage);
            $this->listHandoverSlotsRateLimiter = $factory->create('EasyShipApi-listHandoverSlots');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('EasyShipApi-updateScheduledPackages'), $this->rateLimitStorage);
            $this->updateScheduledPackagesRateLimiter = $factory->create('EasyShipApi-updateScheduledPackages');
        }

        $this->client = $client ?: new Client();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index.
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex(int $hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index.
     *
     * @return int Host index
     */
    public function getHostIndex(): int
    {
        return $this->hostIndex;
    }

    public function getConfig(): Configuration
    {
        return $this->config;
    }

    /**
     * Operation createScheduledPackage.
     *
     * @param CreateScheduledPackageRequest $create_scheduled_package_request
     *                                                                        The request schema for the &#x60;createScheduledPackage&#x60; operation. (required)
     * @param null|string                   $restrictedDataToken              Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackage(
        CreateScheduledPackageRequest $create_scheduled_package_request,
        ?string $restrictedDataToken = null
    ): Package {
        list($response) = $this->createScheduledPackageWithHttpInfo($create_scheduled_package_request, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation createScheduledPackageWithHttpInfo.
     *
     * @param CreateScheduledPackageRequest $create_scheduled_package_request
     *                                                                        The request schema for the &#x60;createScheduledPackage&#x60; operation. (required)
     * @param null|string                   $restrictedDataToken              Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\easyship\v2022_03_23\Package, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageWithHttpInfo(
        CreateScheduledPackageRequest $create_scheduled_package_request,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->createScheduledPackageRequest($create_scheduled_package_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-createScheduledPackage');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->createScheduledPackageRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\easyship\v2022_03_23\Package' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\easyship\v2022_03_23\Package' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\easyship\v2022_03_23\Package', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\easyship\v2022_03_23\ErrorList',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation createScheduledPackageAsync.
     *
     * @param CreateScheduledPackageRequest $create_scheduled_package_request
     *                                                                        The request schema for the &#x60;createScheduledPackage&#x60; operation. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageAsync(
        CreateScheduledPackageRequest $create_scheduled_package_request
    ): PromiseInterface {
        return $this->createScheduledPackageAsyncWithHttpInfo($create_scheduled_package_request)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation createScheduledPackageAsyncWithHttpInfo.
     *
     * @param CreateScheduledPackageRequest $create_scheduled_package_request
     *                                                                        The request schema for the &#x60;createScheduledPackage&#x60; operation. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageAsyncWithHttpInfo(
        CreateScheduledPackageRequest $create_scheduled_package_request,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\easyship\v2022_03_23\Package';
        $request = $this->createScheduledPackageRequest($create_scheduled_package_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-createScheduledPackage');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->createScheduledPackageRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'createScheduledPackage'.
     *
     * @param CreateScheduledPackageRequest $create_scheduled_package_request
     *                                                                        The request schema for the &#x60;createScheduledPackage&#x60; operation. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageRequest(
        CreateScheduledPackageRequest $create_scheduled_package_request
    ): Request {
        // verify the required parameter 'create_scheduled_package_request' is set
        if (null === $create_scheduled_package_request || (is_array($create_scheduled_package_request) && 0 === count($create_scheduled_package_request))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $create_scheduled_package_request when calling createScheduledPackage'
            );
        }

        $resourcePath = '/easyShip/2022-03-23/package';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            'application/json',
            $multipart
        );

        // for model (json/xml)
        if (isset($create_scheduled_package_request)) {
            if ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization($create_scheduled_package_request));
            } else {
                $httpBody = $create_scheduled_package_request;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'POST',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createScheduledPackageBulk.
     *
     * @param CreateScheduledPackagesRequest $create_scheduled_packages_request
     *                                                                          The request schema for the &#x60;createScheduledPackageBulk&#x60; operation. (required)
     * @param null|string                    $restrictedDataToken               Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageBulk(
        CreateScheduledPackagesRequest $create_scheduled_packages_request,
        ?string $restrictedDataToken = null
    ): CreateScheduledPackagesResponse {
        list($response) = $this->createScheduledPackageBulkWithHttpInfo($create_scheduled_packages_request, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation createScheduledPackageBulkWithHttpInfo.
     *
     * @param CreateScheduledPackagesRequest $create_scheduled_packages_request
     *                                                                          The request schema for the &#x60;createScheduledPackageBulk&#x60; operation. (required)
     * @param null|string                    $restrictedDataToken               Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\easyship\v2022_03_23\CreateScheduledPackagesResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageBulkWithHttpInfo(
        CreateScheduledPackagesRequest $create_scheduled_packages_request,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->createScheduledPackageBulkRequest($create_scheduled_packages_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-createScheduledPackageBulk');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->createScheduledPackageBulkRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\easyship\v2022_03_23\CreateScheduledPackagesResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\easyship\v2022_03_23\CreateScheduledPackagesResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\easyship\v2022_03_23\CreateScheduledPackagesResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\easyship\v2022_03_23\ErrorList',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation createScheduledPackageBulkAsync.
     *
     * @param CreateScheduledPackagesRequest $create_scheduled_packages_request
     *                                                                          The request schema for the &#x60;createScheduledPackageBulk&#x60; operation. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageBulkAsync(
        CreateScheduledPackagesRequest $create_scheduled_packages_request
    ): PromiseInterface {
        return $this->createScheduledPackageBulkAsyncWithHttpInfo($create_scheduled_packages_request)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation createScheduledPackageBulkAsyncWithHttpInfo.
     *
     * @param CreateScheduledPackagesRequest $create_scheduled_packages_request
     *                                                                          The request schema for the &#x60;createScheduledPackageBulk&#x60; operation. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageBulkAsyncWithHttpInfo(
        CreateScheduledPackagesRequest $create_scheduled_packages_request,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\easyship\v2022_03_23\CreateScheduledPackagesResponse';
        $request = $this->createScheduledPackageBulkRequest($create_scheduled_packages_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-createScheduledPackageBulk');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->createScheduledPackageBulkRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'createScheduledPackageBulk'.
     *
     * @param CreateScheduledPackagesRequest $create_scheduled_packages_request
     *                                                                          The request schema for the &#x60;createScheduledPackageBulk&#x60; operation. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createScheduledPackageBulkRequest(
        CreateScheduledPackagesRequest $create_scheduled_packages_request
    ): Request {
        // verify the required parameter 'create_scheduled_packages_request' is set
        if (null === $create_scheduled_packages_request || (is_array($create_scheduled_packages_request) && 0 === count($create_scheduled_packages_request))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $create_scheduled_packages_request when calling createScheduledPackageBulk'
            );
        }

        $resourcePath = '/easyShip/2022-03-23/packages/bulk';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            'application/json',
            $multipart
        );

        // for model (json/xml)
        if (isset($create_scheduled_packages_request)) {
            if ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization($create_scheduled_packages_request));
            } else {
                $httpBody = $create_scheduled_packages_request;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'POST',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getScheduledPackage.
     *
     * @param string      $amazon_order_id
     *                                         An Amazon-defined order identifier. Identifies the order that the seller wants to deliver using Amazon Easy Ship. (required)
     * @param string      $marketplace_id
     *                                         An identifier for the marketplace in which the seller is selling. (required)
     * @param null|string $restrictedDataToken Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function getScheduledPackage(
        string $amazon_order_id,
        string $marketplace_id,
        ?string $restrictedDataToken = null
    ): Package {
        list($response) = $this->getScheduledPackageWithHttpInfo($amazon_order_id, $marketplace_id, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation getScheduledPackageWithHttpInfo.
     *
     * @param string      $amazon_order_id
     *                                         An Amazon-defined order identifier. Identifies the order that the seller wants to deliver using Amazon Easy Ship. (required)
     * @param string      $marketplace_id
     *                                         An identifier for the marketplace in which the seller is selling. (required)
     * @param null|string $restrictedDataToken Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\easyship\v2022_03_23\Package, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function getScheduledPackageWithHttpInfo(
        string $amazon_order_id,
        string $marketplace_id,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->getScheduledPackageRequest($amazon_order_id, $marketplace_id);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-getScheduledPackage');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->getScheduledPackageRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\easyship\v2022_03_23\Package' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\easyship\v2022_03_23\Package' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\easyship\v2022_03_23\Package', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\easyship\v2022_03_23\ErrorList',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation getScheduledPackageAsync.
     *
     * @param string $amazon_order_id
     *                                An Amazon-defined order identifier. Identifies the order that the seller wants to deliver using Amazon Easy Ship. (required)
     * @param string $marketplace_id
     *                                An identifier for the marketplace in which the seller is selling. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function getScheduledPackageAsync(
        string $amazon_order_id,
        string $marketplace_id
    ): PromiseInterface {
        return $this->getScheduledPackageAsyncWithHttpInfo($amazon_order_id, $marketplace_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation getScheduledPackageAsyncWithHttpInfo.
     *
     * @param string $amazon_order_id
     *                                An Amazon-defined order identifier. Identifies the order that the seller wants to deliver using Amazon Easy Ship. (required)
     * @param string $marketplace_id
     *                                An identifier for the marketplace in which the seller is selling. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function getScheduledPackageAsyncWithHttpInfo(
        string $amazon_order_id,
        string $marketplace_id,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\easyship\v2022_03_23\Package';
        $request = $this->getScheduledPackageRequest($amazon_order_id, $marketplace_id);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-getScheduledPackage');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->getScheduledPackageRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'getScheduledPackage'.
     *
     * @param string $amazon_order_id
     *                                An Amazon-defined order identifier. Identifies the order that the seller wants to deliver using Amazon Easy Ship. (required)
     * @param string $marketplace_id
     *                                An identifier for the marketplace in which the seller is selling. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function getScheduledPackageRequest(
        string $amazon_order_id,
        string $marketplace_id
    ): Request {
        // verify the required parameter 'amazon_order_id' is set
        if (null === $amazon_order_id || (is_array($amazon_order_id) && 0 === count($amazon_order_id))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_order_id when calling getScheduledPackage'
            );
        }
        if (strlen($amazon_order_id) > 255) {
            throw new \InvalidArgumentException('invalid length for "$amazon_order_id" when calling EasyShipApi.getScheduledPackage, must be smaller than or equal to 255.');
        }
        if (strlen($amazon_order_id) < 1) {
            throw new \InvalidArgumentException('invalid length for "$amazon_order_id" when calling EasyShipApi.getScheduledPackage, must be bigger than or equal to 1.');
        }

        // verify the required parameter 'marketplace_id' is set
        if (null === $marketplace_id || (is_array($marketplace_id) && 0 === count($marketplace_id))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $marketplace_id when calling getScheduledPackage'
            );
        }
        if (strlen($marketplace_id) > 255) {
            throw new \InvalidArgumentException('invalid length for "$marketplace_id" when calling EasyShipApi.getScheduledPackage, must be smaller than or equal to 255.');
        }
        if (strlen($marketplace_id) < 1) {
            throw new \InvalidArgumentException('invalid length for "$marketplace_id" when calling EasyShipApi.getScheduledPackage, must be bigger than or equal to 1.');
        }

        $resourcePath = '/easyShip/2022-03-23/package';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $amazon_order_id,
            'amazonOrderId', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            true, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $marketplace_id,
            'marketplaceId', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            true, // required
            $this->config
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            '',
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'GET',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listHandoverSlots.
     *
     * @param null|ListHandoverSlotsRequest $list_handover_slots_request
     *                                                                   The request schema for the &#x60;listHandoverSlots&#x60; operation. (optional)
     * @param null|string                   $restrictedDataToken         Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listHandoverSlots(
        ?ListHandoverSlotsRequest $list_handover_slots_request = null,
        ?string $restrictedDataToken = null
    ): ListHandoverSlotsResponse {
        list($response) = $this->listHandoverSlotsWithHttpInfo($list_handover_slots_request, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation listHandoverSlotsWithHttpInfo.
     *
     * @param null|ListHandoverSlotsRequest $list_handover_slots_request
     *                                                                   The request schema for the &#x60;listHandoverSlots&#x60; operation. (optional)
     * @param null|string                   $restrictedDataToken         Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\easyship\v2022_03_23\ListHandoverSlotsResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listHandoverSlotsWithHttpInfo(
        ?ListHandoverSlotsRequest $list_handover_slots_request = null,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->listHandoverSlotsRequest($list_handover_slots_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-listHandoverSlots');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->listHandoverSlotsRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\easyship\v2022_03_23\ListHandoverSlotsResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\easyship\v2022_03_23\ListHandoverSlotsResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\easyship\v2022_03_23\ListHandoverSlotsResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\easyship\v2022_03_23\ErrorList',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation listHandoverSlotsAsync.
     *
     * @param null|ListHandoverSlotsRequest $list_handover_slots_request
     *                                                                   The request schema for the &#x60;listHandoverSlots&#x60; operation. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listHandoverSlotsAsync(
        ?ListHandoverSlotsRequest $list_handover_slots_request = null
    ): PromiseInterface {
        return $this->listHandoverSlotsAsyncWithHttpInfo($list_handover_slots_request)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation listHandoverSlotsAsyncWithHttpInfo.
     *
     * @param null|ListHandoverSlotsRequest $list_handover_slots_request
     *                                                                   The request schema for the &#x60;listHandoverSlots&#x60; operation. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listHandoverSlotsAsyncWithHttpInfo(
        ?ListHandoverSlotsRequest $list_handover_slots_request = null,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\easyship\v2022_03_23\ListHandoverSlotsResponse';
        $request = $this->listHandoverSlotsRequest($list_handover_slots_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-listHandoverSlots');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->listHandoverSlotsRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'listHandoverSlots'.
     *
     * @param null|ListHandoverSlotsRequest $list_handover_slots_request
     *                                                                   The request schema for the &#x60;listHandoverSlots&#x60; operation. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listHandoverSlotsRequest(
        ?ListHandoverSlotsRequest $list_handover_slots_request = null
    ): Request {
        $resourcePath = '/easyShip/2022-03-23/timeSlot';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            'application/json',
            $multipart
        );

        // for model (json/xml)
        if (isset($list_handover_slots_request)) {
            if ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization($list_handover_slots_request));
            } else {
                $httpBody = $list_handover_slots_request;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'POST',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateScheduledPackages.
     *
     * @param null|UpdateScheduledPackagesRequest $update_scheduled_packages_request
     *                                                                               The request schema for the &#x60;updateScheduledPackages&#x60; operation. (optional)
     * @param null|string                         $restrictedDataToken               Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function updateScheduledPackages(
        ?UpdateScheduledPackagesRequest $update_scheduled_packages_request = null,
        ?string $restrictedDataToken = null
    ): Packages {
        list($response) = $this->updateScheduledPackagesWithHttpInfo($update_scheduled_packages_request, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation updateScheduledPackagesWithHttpInfo.
     *
     * @param null|UpdateScheduledPackagesRequest $update_scheduled_packages_request
     *                                                                               The request schema for the &#x60;updateScheduledPackages&#x60; operation. (optional)
     * @param null|string                         $restrictedDataToken               Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\easyship\v2022_03_23\Packages, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function updateScheduledPackagesWithHttpInfo(
        ?UpdateScheduledPackagesRequest $update_scheduled_packages_request = null,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->updateScheduledPackagesRequest($update_scheduled_packages_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-updateScheduledPackages');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->updateScheduledPackagesRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\easyship\v2022_03_23\Packages' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\easyship\v2022_03_23\Packages' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\easyship\v2022_03_23\Packages', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\easyship\v2022_03_23\ErrorList',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation updateScheduledPackagesAsync.
     *
     * @param null|UpdateScheduledPackagesRequest $update_scheduled_packages_request
     *                                                                               The request schema for the &#x60;updateScheduledPackages&#x60; operation. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function updateScheduledPackagesAsync(
        ?UpdateScheduledPackagesRequest $update_scheduled_packages_request = null
    ): PromiseInterface {
        return $this->updateScheduledPackagesAsyncWithHttpInfo($update_scheduled_packages_request)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation updateScheduledPackagesAsyncWithHttpInfo.
     *
     * @param null|UpdateScheduledPackagesRequest $update_scheduled_packages_request
     *                                                                               The request schema for the &#x60;updateScheduledPackages&#x60; operation. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function updateScheduledPackagesAsyncWithHttpInfo(
        ?UpdateScheduledPackagesRequest $update_scheduled_packages_request = null,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\easyship\v2022_03_23\Packages';
        $request = $this->updateScheduledPackagesRequest($update_scheduled_packages_request);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'EasyShipApi-updateScheduledPackages');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->updateScheduledPackagesRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'updateScheduledPackages'.
     *
     * @param null|UpdateScheduledPackagesRequest $update_scheduled_packages_request
     *                                                                               The request schema for the &#x60;updateScheduledPackages&#x60; operation. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function updateScheduledPackagesRequest(
        ?UpdateScheduledPackagesRequest $update_scheduled_packages_request = null
    ): Request {
        $resourcePath = '/easyShip/2022-03-23/package';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            'application/json',
            $multipart
        );

        // for model (json/xml)
        if (isset($update_scheduled_packages_request)) {
            if ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization($update_scheduled_packages_request));
            } else {
                $httpBody = $update_scheduled_packages_request;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'PATCH',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option.
     *
     * @return array of http client options
     *
     * @throws \RuntimeException on file opening failure
     */
    protected function createHttpClientOption(): array
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: '.$this->config->getDebugFile());
            }
        }

        return $options;
    }
}
